package com.aibaixun.system.service.impl;

import com.aibaixun.common.constant.ApiConstants;
import com.aibaixun.common.constant.Constants;
import com.aibaixun.common.core.domain.R;
import com.aibaixun.common.utils.HttpUtils;
import com.aibaixun.common.utils.LocalDateTimeUtils;
import com.aibaixun.common.utils.StringUtils;
import com.aibaixun.system.domain.*;
import com.aibaixun.system.domain.dto.WorkOrderAlarmDto;
import com.aibaixun.system.domain.dto.WorkOrderAlarmPageDto;
import com.aibaixun.system.domain.vo.*;
import com.aibaixun.system.service.*;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.aibaixun.system.mapper.WorkOrderAlarmMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
* @author zhangyh
* @description 针对表【work_order_alarm(工单告警信息表)】的数据库操作Service实现
* @createDate 2023-09-26 15:53:06
*/
@Service
public class WorkOrderAlarmServiceImpl extends ServiceImpl<WorkOrderAlarmMapper, WorkOrderAlarm>
    implements WorkOrderAlarmService{

    @Autowired
    private EvsHumanEventService evsHumanEventService;

    @Autowired
    private EvsDoorEventService evsDoorEventService;

    @Autowired
    @Lazy
    private DicmNvrService dicmNvrService;

    @Autowired
    @Lazy
    private DicmWorkOrderService dicmWorkOrderService;

    @Autowired
    private DicmAddressService dicmAddressService;

    @Override
    public R getPage(Page page, WorkOrderAlarmPageDto pageDto) {
        Page<WorkOrderAlarmAllVo> resultPage = this.baseMapper.getPage(page, pageDto);
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        for (WorkOrderAlarmAllVo record : resultPage.getRecords()) {
            EvsHumanEvent evsHumanEvent = evsHumanEventService.getById(record.getEventResultId());
            record.setPicUrl(evsHumanEvent != null ? evsHumanEvent.getPicUrl() : null);

            if(StringUtils.isNotBlank(record.getNvrName()) && record.getNvrName().length() > 5){
                //拼接告警位置
                record.setAddressName(record.getAddressName()+"-"+record.getNvrName().substring(0,5));
            }

            if(StringUtils.isNotBlank(record.getBadgeNum())){
                record.setResidentId(record.getBadgeNum());
            }
            if(StringUtils.isNotBlank(record.getResidentId()) && record.getResidentId().length() > 4){
                String residentId = record.getResidentId();
                record.setResidentId(residentId.substring(0,4)+"****"+residentId.substring(residentId.length()-4));
            }

            if(StringUtils.isBlank(record.getEarliestEnterTime()) || StringUtils.isBlank(record.getLatestEnterTime())){
                continue;
            }
            record.setEarliestEnterTime(LocalDateTime.ofInstant(Instant.ofEpochMilli(Long.parseLong(record.getEarliestEnterTime()))
                , ZoneId.systemDefault()).format(formatter));
            record.setLatestEnterTime(LocalDateTime.ofInstant(Instant.ofEpochMilli(Long.parseLong(record.getLatestEnterTime()))
                , ZoneId.systemDefault()).format(formatter));
        }
        return R.ok(resultPage);
    }

    @Override
    public R<WorkOrderAlarmStatisticsCountVo> getCountStatisticsType(WorkOrderAlarmDto dto) {
        if(dto.getStartAlarmTime() == null || dto.getEndAlarmTime() == null){
            dto.setStartAlarmTime(LocalDateTime.of(LocalDate.now().minusDays(15), LocalTime.MIN));
            dto.setEndAlarmTime(LocalDateTime.of(LocalDate.now(), LocalTime.MAX));
        }
        WorkOrderAlarmStatisticsCountVo countVo = this.baseMapper.getCountStatisticsType(dto);
        if (null != countVo){
            BigDecimal totalCount = new BigDecimal(String.valueOf(countVo.getDoorAlarmCount()+countVo.getIntrusionAlarmCount()+countVo.getIllegalTimeAlarmCount()));
            BigDecimal percent = new BigDecimal("100");
            countVo.setDoorAlarmCountRate(new BigDecimal(String.valueOf(countVo.getDoorAlarmCount()))
                .multiply(percent).divideToIntegralValue(totalCount));
            countVo.setIllegalTimeAlarmCountRate(new BigDecimal(String.valueOf(countVo.getIllegalTimeAlarmCount()))
                .multiply(percent).divideToIntegralValue(totalCount));
            countVo.setIntrusionAlarmCountRate(percent.subtract(countVo.getDoorAlarmCountRate()).subtract(countVo.getIllegalTimeAlarmCountRate()));

        }
        return R.ok(countVo);
    }

    @Override
    public R<List<WorkOrderAlarmStatisticsAddressCountVo>> getCountStatisticsAddress(WorkOrderAlarmDto dto) {
        if(dto.getStartAlarmTime() == null || dto.getEndAlarmTime() == null){
            dto.setStartAlarmTime(LocalDateTime.of(LocalDate.now().minusDays(15), LocalTime.MIN));
            dto.setEndAlarmTime(LocalDateTime.of(LocalDate.now(), LocalTime.MAX));
        }
        return R.ok(this.baseMapper.getCountStatisticsAddress(dto));
    }

    @Override
    public R<List<WorkOrderAlarmStatisticsTrentCountVo>> getCountStatisticsTrend(WorkOrderAlarmDto dto) {
        if(dto.getStartAlarmTime() == null || dto.getEndAlarmTime() == null){
            dto.setStartAlarmTime(LocalDateTime.of(LocalDate.now().minusDays(15), LocalTime.MIN));
            dto.setEndAlarmTime(LocalDateTime.of(LocalDate.now(), LocalTime.MAX));
        }

        List<WorkOrderAlarmStatisticsTrentCountVo> resultList = new LinkedList<>();

        List<WorkOrderAlarmStatisticsTrentCountVo> dataList = this.baseMapper.getCountStatisticsTrend(dto);
        Map<LocalDate,List<WorkOrderAlarmStatisticsTrentCountVo>> dataMap = dataList.stream()
            .collect(Collectors.groupingBy(WorkOrderAlarmStatisticsTrentCountVo::getAlarmDate));
        List<LocalDate> dateList = LocalDateTimeUtils.getAscDateList(dto.getStartAlarmTime().toLocalDate(),dto.getEndAlarmTime().toLocalDate());

        for (LocalDate localDate : dateList) {
            WorkOrderAlarmStatisticsTrentCountVo countVo = new WorkOrderAlarmStatisticsTrentCountVo();
            countVo.setAlarmDate(localDate);
            if(dataMap.get(localDate) == null){
                countVo.setAlarmCount(0);
            }else{
                countVo.setAlarmCount(dataMap.get(localDate).get(0).getAlarmCount());
            }
            resultList.add(countVo);
        }
        return R.ok(resultList);
    }

    @Override
    public R deleteAlarm(Long alarmId) {
        WorkOrderAlarm orderAlarm = this.baseMapper.selectById(alarmId);
        if(orderAlarm == null){
            return R.fail("告警信息不存在！");
        }
        orderAlarm.setDeleted(Constants.INT_1);
        orderAlarm.setDeletedTime(LocalDateTime.now());
        this.baseMapper.updateById(orderAlarm);

        //将删除信息推送给dicm
        DicmNvr dicmNvr = dicmNvrService.getBaseMapper().selectById(orderAlarm.getDeviceId());

        JSONObject dataJson = new JSONObject();
        dataJson.put("alarmId",orderAlarm.getAlarmId());
        dataJson.put("orderId",orderAlarm.getOrderId());
        dataJson.put("alarmType",orderAlarm.getAlarmType());
        dataJson.put("deviceId",orderAlarm.getDeviceId());
        dataJson.put("rtspUrl",orderAlarm.getRtspUrl());
        dataJson.put("alarmTime",orderAlarm.getAlarmTime());
        dataJson.put("nvrName",dicmNvr.getNvrName());

        //拼接告警位置
        DicmAddress address = dicmAddressService.getBaseMapper().selectById(dicmNvr.getAddressId());
        dataJson.put("addressName",address.getAddressName()+"-"+dicmNvr.getNvrName().substring(0,5));

        if(orderAlarm.getOrderId() != null){
            DicmWorkOrder workOrder = dicmWorkOrderService.getBaseMapper().selectById(orderAlarm.getOrderId());
            dataJson.put("personName",workOrder.getPersonName());
            dataJson.put("personPhone",workOrder.getPersonPhone());
            dataJson.put("residentId",workOrder.getResidentId());
            dataJson.put("badgeNum",workOrder.getBadgeNum());
            dataJson.put("earliestEnterTime",workOrder.getEarliestEnterTime());
            dataJson.put("latestEnterTime",workOrder.getLatestEnterTime());
        }
        dataJson.put("picUrl",orderAlarm.getPicUrl());
        dataJson.put("deletedTime",orderAlarm.getDeletedTime());
        dataJson.put("alarmLevel",orderAlarm.getAlarmType().intValue() == 1 ?
            "三级" : (orderAlarm.getAlarmType().intValue() == 2 ? "一级" : "二级")
        );

        Object jsonObject = HttpUtils.sendJsonPostRequest(ApiConstants.IP_ADDRESS + ApiConstants.WORK_ORDER_ALARM_SEND,dataJson.toJSONString());
        System.out.println("工单告警推送结果："+jsonObject);
        return R.ok();
    }

    @Override
    public R<List<WorkOrderAlarmAllVo>> getList(WorkOrderAlarmDto dto) {
        List<WorkOrderAlarmAllVo> resultList = this.baseMapper.getList(dto);
        for (WorkOrderAlarmAllVo record : resultList) {
            if(record.getAlarmType().intValue() == Constants.INT_1){
                EvsDoorEvent evsDoorEvent = evsDoorEventService.getById(record.getEventResultId());
                record.setPicUrl(evsDoorEvent != null ? evsDoorEvent.getFirstPicUrl() : null);
            }else{
                EvsHumanEvent evsHumanEvent = evsHumanEventService.getById(record.getEventResultId());
                record.setPicUrl(evsHumanEvent != null ? evsHumanEvent.getPicUrl() : null);
            }

            if(StringUtils.isBlank(record.getEarliestEnterTime()) || StringUtils.isBlank(record.getLatestEnterTime())){
                continue;
            }
            record.setEarliestEnterTime(String.valueOf(LocalDateTime.ofInstant(Instant.ofEpochMilli(Long.parseLong(record.getEarliestEnterTime()))
                , ZoneId.systemDefault())));
            record.setLatestEnterTime(String.valueOf(LocalDateTime.ofInstant(Instant.ofEpochMilli(Long.parseLong(record.getLatestEnterTime()))
                , ZoneId.systemDefault())));
        }
        return R.ok(resultList);
    }

    @Override
    public R<List<WorkOrderAlarmDeviceVo>> getOrderAlarmDevice(WorkOrderAlarmDto dto) {
        if(dto.getStartAlarmTime() == null || dto.getEndAlarmTime() == null){
            dto.setStartAlarmTime(LocalDateTime.of(LocalDate.now(),LocalTime.MIN));
            dto.setEndAlarmTime(LocalDateTime.of(LocalDate.now(),LocalTime.MAX));
        }
        List<WorkOrderAlarmDeviceVo> deviceVoList = this.baseMapper.getOrderAlarmDevice(dto);
        if(deviceVoList.size() == 0){
            return R.ok(deviceVoList);
        }
        for (WorkOrderAlarmDeviceVo deviceVo : deviceVoList) {
            dto.setDeviceId(deviceVo.getDeviceId());
            WorkOrderAlarmAllVo alarmAllVo = this.baseMapper.getOrderAlarmDetail(dto);
            if(alarmAllVo == null){
                continue;
            }
            deviceVo.setDeviceName(alarmAllVo.getNvrName());
            deviceVo.setAlarmInfo(alarmAllVo);
        }
        return R.ok(deviceVoList);
    }

}




